package com.hmall.service;

import com.google.gson.Gson;
import com.hdmall.business.common.common.Const;
import com.hmall.config.JPushConst;
import com.hdmall.business.common.common.ServerResponse;
import com.hdmall.business.common.util.RabbitUtil;
import com.hmall.mapper.SysCustomerMapper;
import com.hmall.mapper.SysDeptCustomerMapper;
import com.hmall.mapper.SysUserDeptMapper;
import com.hmall.mapper.SysUserMapper;
import com.hmall.model.MallPushMessage;
import com.hmall.model.SysCustomer;
import com.hmall.model.SysUser;
import com.hdmall.business.common.util.JsonUtils;
import com.hdmall.business.common.util.NumberUtil;
import com.hmall.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.*;

/**
 * @ClassName IMService
 * @Description //
 * @Author zhoutao
 * @Date 2018/11/5 11:01
 * @Version 2.0
 **/
@Service
@Slf4j
public class IMService {

    private  SysUserMapper userMapper;

    private  SysUserDeptMapper sysUserDeptMapper;

    private  SysDeptCustomerMapper sysDeptCustomerMapper;

    private  SysCustomerMapper customerMapper;

    private  SysCustomerMapper sysCustomerMapper;

    private  JpushService jpushService;

    private  JedisPool jedisPool;

    @Autowired
    JPushConst jPushConst;



    @Autowired
    public IMService(JedisPool jedisPool, SysUserMapper userMapper, SysUserDeptMapper sysUserDeptMapper, SysDeptCustomerMapper sysDeptCustomerMapper, SysCustomerMapper sysCustomerMapper, SysCustomerMapper customerMapper, JpushService jpushService) {
        this.jedisPool = jedisPool;
        this.userMapper = userMapper;
        this.sysUserDeptMapper = sysUserDeptMapper;
        this.sysDeptCustomerMapper = sysDeptCustomerMapper;
        this.sysCustomerMapper = sysCustomerMapper;
        this.customerMapper = customerMapper;
        this.jpushService = jpushService;
    }


    /**
     * @Date 2018/11/5 11:12
     * @Param [userId, type, message]
     * @return com.hmall.common.ServerResponse
     * @Description // 用户给后台发送信息
     *
     * 2018/11/6 改为后台绑定客服选择一个
     * username--->sendMessage to ---> backUsername
     */
    public ServerResponse<String> sendMessage(String username, String backUsername, String messageJsonStr, String exchange) {

        username = username.split("-")[0];
        backUsername = backUsername.split("-")[0];
//        messageJsonStr = "{\"sendModel\":{\"avator\":\"http://huangyonghui.oss-cn-beijing.aliyuncs.com/imgupload/1538198934701.jpg?Expires=1853558929&OSSAccessKeyId=LTAIp8OhI23AvQo5&Signature=Ok32kwKfR8EgBznXpDvwgGfPba0%3D\"," +
//                "\"userId\":344,\"username\":\"15669055861\"},"
//                + "\"receiveModel\":{\"avator\":\"http://huangyonghui.oss-cn-beijing.aliyuncs.com/imgupload/1541492403782.png?Expires=1856852396&OSSAccessKeyId=LTAIp8OhI23AvQo5&Signature=jnltIoNFjWNMcuWt9Z0Kw%2F8nmWw%3D\"," +
//                "\"userId\":352,\"username\":\"hyh\"}," + "\"content\":\"你好\"," + "\"type\":\"word\"," + "\"url\":\"\"," + "\"time\":110}";

        MessageJsonVo messageJsonVo = JsonUtils.jsonStrToObject(messageJsonStr, MessageJsonVo.class);
        //用户给后台发信息
        String position;
        if(Const.BACK_MESSAGE_EXCHG.equals(exchange)){
            if(messageJsonVo.getSendModel().getUsername().equals(username)){
                position = "right";
            }else{
                position = "left";
            }
        }else{
            if(messageJsonVo.getSendModel().getUsername().equals(username)){
                position = "left";
            }else{
                position = "right";
            }
        }
        messageJsonVo.setPosition(position);
        messageJsonVo.setTime(System.currentTimeMillis());
        messageJsonVo.setMessageNo(NumberUtil.createIMMessageNo());
        messageJsonVo.setIsRead(0);
        messageJsonStr = JsonUtils.objectToJsonStr(messageJsonVo);

        //给三端
        RabbitUtil.rabbitPushForDirect(exchange, "message", "PC-" + backUsername, messageJsonStr, "direct");
        RabbitUtil.rabbitPushForDirect(exchange, "message", "IOS-" + backUsername, messageJsonStr, "direct");
        RabbitUtil.rabbitPushForDirect(exchange, "message", "ANDROID-" + backUsername, messageJsonStr, "direct");

        log.info("rabbitmq推送成功");

        //把消息存到redis里
        Jedis jedis = jedisPool.getResource();

        //PC额外推送
        pcOtherPush(backUsername, jedis);

        log.info("给PC浏览器提醒消息成功");
        //——————————————

        //手机端额外推送
        mobileOtherPush(backUsername, messageJsonVo, jedis, messageJsonStr, exchange);

        //————————————————————
        log.info("给手机极光推送消息提醒成功");

        //未读消息数目存储到 noReadCount-receive-send 里面
        //接受方  发送方 未读数是针对于接收方来说


        String noReadKey = "noReadCount" + "-" + backUsername + "-" + username;
        Integer value = 0;
        if(jedis.exists(noReadKey)){
             value = Integer.valueOf(jedis.get(noReadKey));
        }
        jedis.set(noReadKey, String.valueOf((value + 1)));

        //这个接口如果用户给客服发送存储的时候要反一下
        if(Const.FRONT_MESSAGE_EXCHG.equals(exchange)){
        String temp = username;
        username = backUsername;
        backUsername = temp;
        }
        //ttl设置三天
        long time = 60 * 60 * 24 * 3 * 1000;
        //队列id
        //用户得到的信息 用户在右 客服在左边
        String key = "IM-" + username;

        //用户为主键
        //存储信息
        jedis.zadd(key, System.currentTimeMillis() + time, messageJsonStr);

        String backKey = "IM-" + "back-" + backUsername;
        if("left".equals(position)){
            position = "right";
        }else{
            position = "left";
        }
        messageJsonVo.setPosition(position);
        messageJsonVo.setIsRead(0);
        messageJsonStr = JsonUtils.objectToJsonStr(messageJsonVo);
        //后台人员作为主键
        jedis.zadd(backKey, System.currentTimeMillis() + time, messageJsonStr);

        jedis.close();
        return ServerResponse.createBySuccess("发送成功");
    }

    /**
     * @Date 2018/11/8 10:36
     * @Param [backUsername, jedis]
     * @return void
     * @Description // pc额外推送 当会话页面关闭需要提醒用rabbitmq
     */
    private void pcOtherPush(String backUsername, Jedis jedis){
        //得到浏览器状态
        //PC关闭时候推送信息
        //——————————————
        String typeKey = "PC-device-" + backUsername;
        String typeValue = "";
        if(jedis.exists(typeKey)){
            typeValue = jedis.get(typeKey);
        }

        if(!Const.DEVICE_OPEN.equals(typeValue)){

            MallPushMessage mallPushMessage = new MallPushMessage();
            mallPushMessage.setType("message_type");
            mallPushMessage.setBody("有新消息");
            RabbitUtil.rabbitPushForDirect(Const.HDMALL_DIRECT_EXCHG, null, backUsername, JsonUtils.objectToJsonStr(mallPushMessage), "direct");
        }
    }

    /**
     * @Date 2018/11/8 10:39
     * @Param [backUsername, messageJsonVo, jedis, messageJsonStr]
     * @return void
     * @Description // 手机关闭额外信息 当手机关闭会话页面发送极光推送
     */
    private void mobileOtherPush(String backUsername, MessageJsonVo messageJsonVo, Jedis jedis, String messageJsonStr, String exchange){

        String secret, appKey;
        //如果是前端推送
        if(Const.FRONT_MESSAGE_EXCHG.equals(exchange)){
            secret = jPushConst.JPUSH_MALL_SECRET;
            appKey = jPushConst.JPUSH_MALL_APPKEY;
        }else{
            secret = jPushConst.JPUSH_BACK_SECRET;
            appKey = jPushConst.JPUSH_BACK_APPKEY;
        }

        //手机关闭时候信息
        String alias = "";
        if(jedis.exists(Const.ALIAS_PRE + backUsername)){
            alias = jedis.get(Const.ALIAS_PRE + backUsername);
        }
        String agent = "";
        if(!"".equals(alias)){
            agent = alias.split("_")[0];
        }

        //得到手机端状态
        String phoneKey = agent + "-device-" + backUsername;
        String phoneValue;
        String content = "";
        switch (messageJsonVo.getType()){
            case "img" : {
                content = "[图片]";
                break;
            }
            case "word": {
                content = messageJsonVo.getContent();
                break;
            }
            case "voice":{
                content = "您有一条新消息";
                break;
            }
            default:{
                break;
            }
        }
        String sendName = messageJsonVo.getSendModel().getRealName();
        if(sendName == null){
            //注意 极光推送键值不能为null
            sendName = "未指定真实姓名";
        }

        if(jedis.exists(phoneKey)){
            phoneValue = jedis.get(phoneKey);
            //设备信息 发送人名称  发送内容
            if(Const.DEVICE_CLOSE.equals(phoneValue)) {
                jpushService.remindMessage(sendName, messageJsonVo.getSendModel().getUserId(), content, alias, messageJsonStr, secret, appKey);
            }
        }else{
            //默认要推送  如果alias不是空需要推送
            if(!"".equals(alias)) {
                jpushService.remindMessage(sendName, messageJsonVo.getSendModel().getUserId(), content, alias, messageJsonStr, secret, appKey);
            }
        }


    }

    /**
     * @Date 2018/11/7 16:59
     * @Param [username, backUserId, type, pageNum, pageSize]
     * @return com.hmall.common.ServerResponse<com.hmall.vo.PageVo>
     * @Description  用户看到的消息列表
     */
    public ServerResponse<PageVo<MessageJsonVo>> getMessageList(String username, Integer backUserId, String type, Integer pageNum, Integer pageSize) {

        String header = "";
        if(Const.FRONT.equals(type)){
            header = "IM-";
        }else if(Const.BACK.equals(type)){
            header = "IM-" + "back-";
        }

        //发送人可以是176-x 176-z 176 但是redis中key是176
        username = username.split("-")[0];

        List<MessageJsonVo> messageJsonVoArrayList = new ArrayList<>();
        Jedis jedis = jedisPool.getResource();
        Set<String> set;
        String key = header + username;


        if(jedis.exists(key)) {
            set = jedis.zrevrange(key, 0, -1);
            for (String id : set) {
                if (System.currentTimeMillis() >= jedis.zscore(key, id).longValue()) {
                    jedis.zrem(key, id);
                }
                System.out.println(id);
                MessageJsonVo messageJsonVo = JsonUtils.jsonStrToObject(id, MessageJsonVo.class);
//                userMapper.selectByUsername()
                Integer userId = userMapper.selectByUserName1(username.split("-")[0]).getUserId();
                boolean check = (userId.equals(messageJsonVo.getReceiveModel().getUserId()) && backUserId.equals(messageJsonVo.getSendModel().getUserId())) ||
                        (userId.equals(messageJsonVo.getSendModel().getUserId()) && backUserId.equals(messageJsonVo.getReceiveModel().getUserId()));
                if (check) {
                    messageJsonVoArrayList.add(messageJsonVo);
                }
            }
        }
        jedis.close();

        Integer count = messageJsonVoArrayList.size();
        Integer start = pageSize * (pageNum - 1);
        Integer end = Math.min(count, start + pageSize);
        messageJsonVoArrayList = messageJsonVoArrayList.subList(start, end);
        PageVo<MessageJsonVo> pageVo = new PageVo<>(pageNum, pageSize, count, messageJsonVoArrayList);
        return ServerResponse.createBySuccess(pageVo);
    }

    /**
     * @Date 2018/12/6 16:23
     * @Param [username]
     * @return java.util.List<java.lang.Integer>
     * @Description  得到业务员的人员列表
     */
    List<Integer> getSalsmanIdList(String username){
        username = username.split("-")[0];
        List<SysUser> subUserList = userMapper.selectSubUser(username);
        Set<Integer> salesmanIdSet = new HashSet<>();
        for(SysUser subUser : subUserList){
            if(!(subUser.getUsername().equals(username.split("-")[0]) || subUser.getUsername().contains("-"))) {
                continue;
            }
            SysCustomer customer = sysCustomerMapper.selectCustomerByUserId(subUser.getUserId());
            if(customer == null){
                continue;
            }
            Integer salesmanId = customer.getSalesmanId();
            salesmanIdSet.add(salesmanId);
        }
        List<Integer> salesmanIdList = new ArrayList<>(salesmanIdSet);

        return salesmanIdList;
    }


    public ServerResponse<MessageJsonListVo> getInformationBeforeSend(SysUser user) {

        //2018/12/6以业务员维度拉人员列表
        //得到所有办事处的人员列表
        String username = user.getUsername().split("-")[0];


        List<Integer> salesmanIdList = getSalsmanIdList(username);
        List<SysUser> salesmanUserList = new ArrayList<>();
        if(salesmanIdList.size()!= 0) {
            salesmanUserList = userMapper.selectByUserIdList(salesmanIdList);
        }

          MessageJsonListVo messageJsonListVo = new MessageJsonListVo();
          SysUser sendUser = user;
          //发送人
          SendModel sendModel = new SendModel(sendUser.getUserId(), sendUser.getUsername(), sendUser.getAvatar(), sendUser.getRealName());


        List<ReceiveModel> receiveModelList = new ArrayList<>();
          for(SysUser salesmanUser : salesmanUserList){
              //和设计确认是写死的
              String customerName = "义乌华鼎锦纶股份有限公司";
              ReceiveModel receiveModel = new ReceiveModel(salesmanUser.getUserId(), salesmanUser.getUsername(), salesmanUser.getAvatar(), salesmanUser.getRealName());
              receiveModel.setCustomerName(customerName);
              receiveModelList.add(receiveModel);
          }

          messageJsonListVo.setReceiveModelList(receiveModelList);
          messageJsonListVo.setSendModel(sendModel);
          return ServerResponse.createBySuccess(messageJsonListVo);
    }

    /**
     * @Date 2018/11/6 14:52
     * @Param [userId]
     * @return com.hmall.common.ServerResponse
     * @Description // 客服得到用户信息列表
     */
    public ServerResponse<BackBeforeSendInformation> backGetInformationBeforeSend(Integer userId, String type) {

        boolean check = "front".equals(type);
        SysUser user = userMapper.selectByPrimaryKey(userId);
        BackBeforeSendInformation backBeforeSendInformation = new BackBeforeSendInformation();
        SendModel sendModel = new SendModel();
        sendModel.setAvator(user.getAvatar());
        sendModel.setUserId(userId);
        sendModel.setUsername(user.getUsername());
        sendModel.setRealName(user.getRealName());

        List<ReceiveModel> receiveModelList = new ArrayList<>();
        List<Integer> userIdList = new ArrayList<>();
        //如果是后端
        if(!check) {
            //得到与该客服（业务员）绑定的公司， 得到和公司绑定的用户
            List<Integer> customerIdList = customerMapper.selectCustomerIdLisstBySalsemanId(userId);


            for (Integer customerId : customerIdList) {
                userIdList.addAll(sysUserDeptMapper.selectUserIdListByCustomerId(customerId));
            }
        }else{
            //如果是前端
            //找到该用户的所有的业务员

            userIdList.addAll(getSalsmanIdList(user.getUsername()));

        }

//        if(userIdList == null || (userIdList != null && userIdList.size() == 0)){

        List<SysUser> userList = new ArrayList<>();
        if(userIdList != null && userIdList.size() != 0) {
            userList = userMapper.selectByUserIdList(userIdList);
        }

        //用户去重
        Set<String> usernameSet = new HashSet<>();
        List<SysUser> newUserList = new ArrayList<>();
        for(SysUser subUser : userList){
            String username = subUser.getUsername().split("-")[0];
            if(usernameSet.contains(username)) {
                continue;
            }
            newUserList.add(subUser);
            usernameSet.add(username);
        }
        usernameSet.clear();
        userList.clear();
        //176-X 176-Z 都要变成给176发送信息但是要附加公司信息
        //接收方是用户
        for(SysUser subUser : newUserList){
//            SysCustomer realCustomer= sysCustomerMapper.selectCustomerByUserId(subUser.getUserId());
//            String customerName = realCustomer.getBusName();
//            Integer customerId = realCustomer.getCustomerId();
            String sendName = subUser.getUsername().split("-")[0];
            subUser = userMapper.selectByUserName1(sendName);
            SysCustomer customer = sysCustomerMapper.selectCustomerByUserId(subUser.getUserId());
            ReceiveModel receiveModel = new ReceiveModel(subUser.getUserId(), subUser.getUsername(), subUser.getAvatar(), subUser.getRealName());
            if(customer != null) {
                receiveModel.setCustomerName(customer.getBusName());
                receiveModel.setCustomerId(customer.getCustomerId());
            }
            receiveModelList.add(receiveModel);
        }

        //遍历一遍消息把每个用户最新的一条放进去
        Jedis jedis = jedisPool.getResource();

        String backUsername = userMapper.selectByPrimaryKey(userId).getUsername();
        //500客户
        Map<String, String> map = new HashMap<>(500);
        //redis中自己是接收方
        String messageKey;
        if(!check) {
            messageKey = "IM-back-" + backUsername;
        }else{
            messageKey = "IM-" + backUsername;
        }
        Set<String> set = jedis.zrevrange(messageKey, 0, -1);

        //设置最近的一条消息
        for(String id : set){
            //如果最近信息数目已经够了就不再需要查找
            if(map.size() == receiveModelList.size()) {
                break;
            }
            if (System.currentTimeMillis() >= jedis.zscore(messageKey, id).longValue()) {
                jedis.zrem(messageKey, id);
            }
            MessageJsonVo messageJsonVo = JsonUtils.jsonStrToObject(id, MessageJsonVo.class);
            String sendUsername = messageJsonVo.getSendModel().getUsername();
            String receiveUsername = messageJsonVo.getReceiveModel().getUsername();
            String customerUsername;
            if(backUsername.equals(sendUsername)){
                customerUsername = receiveUsername;
            }else{
                customerUsername = sendUsername;
            }
            if(null != customerUsername && !map.containsKey(customerUsername)){
                map.put(customerUsername, id);
            }
        }

        List<ReceiveInformation> receiveInformationList = new ArrayList<>();

        for(ReceiveModel receiveMode : receiveModelList){
            ReceiveInformation receiveInformation = new ReceiveInformation();
            String key = "noReadCount" + "-" + backUsername+ "-" + receiveMode.getUsername() ;
            Integer noReadCount = 0;
            if(jedis.exists(key)) {
                noReadCount = Integer.valueOf(jedis.get(key));
            }
            receiveInformation.setReceiveModel(receiveMode);
            receiveInformation.setNoReadCount(noReadCount);
            String customerUsername = receiveMode.getUsername();
            String latestMessage = "";
            if(null != map.get(customerUsername)){
                latestMessage = map.get(customerUsername);
            }
            receiveInformation.setLatestMessage(latestMessage);
            receiveInformationList.add(receiveInformation);
        }
        jedis.close();

        backBeforeSendInformation.setReceiveInformationList(receiveInformationList);
        backBeforeSendInformation.setSendModel(sendModel);

        return ServerResponse.createBySuccess(backBeforeSendInformation);

    }

    public ServerResponse<String> saveCloseTime(String username, String type, String device) {

        Jedis jedis = jedisPool.getResource();
        String key = device + "-device-" + username;
        jedis.set(key, type);
        return ServerResponse.createBySuccess("设置状态成功");
    }

    public ServerResponse<String> checkAllRead(String username, String sendUsername) {

        username = username.split("-")[0];
        sendUsername = sendUsername.split("-")[0];
        Jedis jedis = jedisPool.getResource();
        String key = "noReadCount" + "-" + username + "-" + sendUsername;
        if(jedis.exists(key)){
            jedis.set(key, 0 + "");
        }
        jedis.close();
        return ServerResponse.createBySuccess("设置成已读成功");

    }

    /**
     * @Date 2019/1/17 15:43
     * @Param [username, sendUsername, messageNo] 
     * @return com.hmall.common.ServerResponse
     * @Description 设置某条语音为已读
     */
    public ServerResponse checkSoundRead(String username, Long messageNo) {

        //先判断是前端用户还是后端用户
        SysUser user = userMapper.selectByUserName1(username);
        String preKey;
        if (user.getDeptId() != null) {
            //说明是后端的
            preKey = "IM-back-";
        } else {
            preKey = "IM-";
        }

        //1.将该条message设置为已读
        //2.将noReadCount -1

        try (Jedis jedis = jedisPool.getResource()) {
            String key = preKey + username;
            Set messageSet = jedis.zrange(key, 0, -1);
            Iterator iter = messageSet.iterator();
            Gson gson = new Gson();
            while (iter.hasNext()) {

                String jsonStr = (String) iter.next();
                MessageJsonVo messageJsonVo = gson.fromJson(jsonStr, MessageJsonVo.class);
                if (messageNo.equals(messageJsonVo.getMessageNo())) {
                    messageJsonVo.setIsRead(1);
                    Double score = jedis.zscore(key, jsonStr);
                    jedis.zrem(key, jsonStr);
                    String jsonVoStr = gson.toJson(messageJsonVo);
                    jedis.zadd(key, score, jsonVoStr);

                    //noReadCount-1
                    SendModel sendModel = messageJsonVo.getSendModel();
                    String sendName = sendModel.getUsername();
                    String noReadKey = "noReadCount-" + username + "-" + sendName;
                    if(jedis.exists(noReadKey)){
                        int count = Math.max(0, Integer.parseInt(jedis.get(noReadKey)) - 1);
                        jedis.set(noReadKey, String.valueOf(count));
                    }
                    break;
                }
            }
        }catch (Exception e){
            return ServerResponse.createByErrorMessage("设置已读失败");
        }
        return ServerResponse.createBySuccess("设置已读成功");
    }
}
